<template>
  <div class="member">
    <v-data-table
      :headers="headers"
      :items="users"
      :options.sync="options"
      :page.sync="pager.page"
      :items-per-page.sync="pager.pageSize"
      :server-items-length="pager.total"
      :loading="loading"
      @update:page="handlePage"
      @update:items-per-page="handlePageSize"
    >
      <template v-slot:top>
        <v-toolbar flat color="white">
          <v-toolbar-title>Memberships</v-toolbar-title>
          <v-divider
            class="mx-4"
            inset
            vertical
          ></v-divider>
          <v-toolbar-items>
            <v-text-field
              v-model="filteredUser"
              label="Search"
              class="mt-4"
              clearable
              append-icon="mdi-magnify"
              @click:clear="clearFilter"
              @click:append="handleFilter"
              @keypress.enter.prevent="handleFilter"
            ></v-text-field>
          </v-toolbar-items>

          <v-spacer></v-spacer>
          <v-dialog persistent v-model="dialog" max-width="640px">
            <template v-slot:activator="{ on }">
              <v-btn color="primary" dark class="mb-2" v-on="on">New Item</v-btn>
            </template>
            <v-card>
              <v-card-title>
                <span class="headline">{{ formTitle }}</span>
              </v-card-title>
              <v-card-text>
                <v-container>
                  <v-form ref="editForm" v-model="valid">
                    <v-row>
                      <v-text-field
                        v-model="editedItem.username"
                        :rules="rules.username"
                        label="Username"
                        :disabled="!!editedItem.id"
                      ></v-text-field>
                    </v-row>
                    <v-row>
                      <v-text-field
                        v-model="editedItem.password"
                        :rules="rules.password"
                        label="Password"
                        :hint="passwordHint"
                      ></v-text-field>
                    </v-row>
                    <v-row>
                      <v-select
                        v-model="editedItem.userType"
                        :items="userTypes"
                        item-text="name"
                        item-value="id"
                        label="Type"
                        persistent-hint
                        return-object
                        single-line
                        :rules="rules.userType"
                      ></v-select>
                    </v-row>
                    <v-row v-if="editedItem.id === currentUser.id">
                      <v-col sm="12">
                        <v-alert type="warning">
                          You cannot change your own status.
                        </v-alert>
                      </v-col>
                    </v-row>
                    <v-row>
                      <v-col sm="12" md="6">
                        <v-switch
                          v-model="editedItem.admin"
                          label="Admin"
                          :disabled="editedItem.id === currentUser.id"
                        ></v-switch>
                      </v-col>
                      <v-col sm="12" md="6">
                        <v-switch
                          v-model="editedItem.suspended"
                          label="Suspended"
                          :disabled="editedItem.id === currentUser.id"
                        ></v-switch>
                      </v-col>
                    </v-row>
                  </v-form>
                </v-container>
              </v-card-text>
              <v-card-actions>
                <v-spacer></v-spacer>
                <v-btn color="blue darken-1" text @click="hideDialog">Cancel</v-btn>
                <v-btn color="blue darken-1" text :disabled="!valid" :loading="loading" @click="handleSave">Save</v-btn>
              </v-card-actions>
            </v-card>
          </v-dialog>
        </v-toolbar>
      </template>
      <template v-slot:item.userType="{item}">
        {{item.userType?item.userType.name:''}}
      </template>
      <template v-slot:item.suspended="{item}">
        {{item.suspended?'Y':'N'}}
      </template>
      <template v-slot:item.sex="{item}">
        {{['Unknown', 'Male', 'Female'][item.sex]}}
      </template>
      <template v-slot:item.admin="{item}">
        {{item.admin?'Admin':'User'}}
      </template>
      <template v-slot:item.updateTime="{item}">
        {{item.updateTime | moment('YYYY-MM-DD HH:mm:ss')}}
      </template>
      <template v-slot:item.action="{ item }">
        <v-icon
          small
          class="mr-2"
          @click="editItem(item.id)"
          :disabled="loading"
        >
          mdi-pencil
        </v-icon>
        <v-icon
          small
          v-if="currentUser.id !== item.id"
          @click="deleteItem(item.id)"
        >
          mdi-delete
        </v-icon>
      </template>
    </v-data-table>
    <v-dialog
      v-model="deleteDialog.visible"
      max-width="600px"
      persistent
    >
      <v-card>
        <v-card-title class="headline">Confirmation</v-card-title>
        <v-card-text>
          Are you sure to delete this item?
        </v-card-text>
        <v-card-actions>
          <v-spacer/>
          <v-btn text @click.stop="hideDeleteDialog">No</v-btn>
          <v-btn color="green darken-1" text @click="handleDelete" :loading="loading">Delete it anyway</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
</template>

<script>
  import {addUser, deleteUser, getUser, getUsers, updateUser} from "../../api/users";
  import {getUserTypes} from "../../api/usertype";

  export default {
    name: 'member',
    data: () => ({
      editedItem: {
        id: null,
        username: null,
        password: null,
        suspended: false,
        updateTime: null,
        admin: false,
        userType: null,
      },
      headers: [
        { text: '#', value: 'id', sortable: false },
        { text: 'Username', value: 'username', sortable: false },
        { text: 'Type', value: 'userType', sortable: false },
        { text: 'Auth', value: 'admin', sortable: false },
        { text: 'Nickname', value: 'nickname', sortable: false },
        { text: 'Suspended', value: 'suspended', sortable: false },
        { text: 'Gender', value: 'sex', sortable: false },
        { text: 'Address', value: 'address', sortable: false },
        { text: 'Mobile', value: 'mobile', sortable: false },
        { text: 'Last Modify Time', value: 'updateTime', sortable: false },
        { text: 'Actions', value: 'action', sortable: false },
      ],
      users: [],
      filteredUser: '',
      loading: false,
      pager: {
        page: 1,
        pageSize: 15,
        total: 1,
        totalPages: 1,
      },
      options: {},
      valid: false,
      dialog: false,
      formTitle: 'New Item',
      deleteDialog: {
        visible: false,
        itemToDelete: null,
      },
      userTypes: [],
      rules: {
        username: [
          v => !!v || 'Username is required',
          v => !!v && v.length >= 5 || 'Username length must be 5 or more'
        ],
        password: [v => !v || v.length >= 6 || 'Password length must be 6 or more'],
        userType: [v => !!v || 'User type is required'],
      }
    }),
    computed: {
      currentUser() {
        return this.$store.getters.user;
      },
      passwordHint() {
        if (this.editedItem.id) return 'Leave out if password is unchanged';
        return '\'123456\' will be used as default if password field is empty.'
      }
    },
    methods: {
      clearFilter() {
        this.filteredUser = '';
        this.handleFilter();
      },
      handleFilter() {
        this.pager.page = 1;
        this.pager.total = 0;
        this.pager.totalPages = 0;
        this.loadUsers();
      },
      handlePage(page) {
        this.pager.page = page;
        this.loadUsers();
      },
      handlePageSize(size) {
        if (size === -1) {
          this.$toasted.error('Page size cannot be "All"');
          this.pager.pageSize = 15;
        }
        else {
          this.pager.pageSize = size;
          this.loadUsers();
        }
      },
      resetItem() {
        Object.keys(this.editedItem).forEach(k => this.editedItem[k] = null);
        this.editedItem.suspended = false;
        this.editedItem.admin = false;
      },
      hideDialog() {
        this.$refs['editForm'].reset();
        this.dialog = false;
        this.resetItem();
        this.formTitle = 'New Item';
      },
      hideDeleteDialog() {
        this.loading = false;
        this.deleteDialog.visible = false;
        this.deleteDialog.itemToDelete = null;
      },
      editItem(id) {
        getUser(id).subscribe(res => {
          if (res.data) {
            Object.keys(this.editedItem).forEach(k => this.editedItem[k] = res.data[k]);
            this.dialog = true;
            this.formTitle = 'Edit'
          }
        })
      },
      deleteItem(id) {
        this.deleteDialog.itemToDelete = id;
        this.deleteDialog.visible = true;
      },
      handleSave() {
        if (this.editedItem.id) this.handleUpdate();
        else this.handleAdd();
      },
      handleAdd() {
        if (!this.editedItem.id) {
          this.loading = true;
          addUser(this.editedItem).subscribe(res => {
            if (res.data) {
              this.$toasted.info('User added');
              this.loadUsers();
              this.hideDialog();
            }
            else {
              this.$toasted.error('No response');
            }
          }, err => {
            this.$toasted.error(err);
            this.loading = false;
          })
        }
      },
      handleDelete() {
        if (this.deleteDialog.itemToDelete) {
          this.loading = true;
          deleteUser(this.deleteDialog.itemToDelete).subscribe(res => {
            if (res.status === 200) {
              this.$toasted.info('User deleted');
              this.loadUsers();
            }
            else {
              this.$toasted.error('No response');
            }
            this.hideDeleteDialog();
          }, err => {
            this.$toasted.error(err);
            this.hideDeleteDialog();
          })
        }
      },
      handleUpdate() {
        if (this.editedItem.id) {
          this.loading = true;
          updateUser(this.editedItem).subscribe(res => {
            if (res.data) {
              this.$toasted.info('User updated');
              this.loadUsers();
              this.hideDialog();
            }
            else {
              this.$toasted.error('No response');
            }
          }, err => {
            this.$toasted.error(err);
            this.loading = false;
          })
        }
      },
      loadUserTypes() {
        getUserTypes().subscribe(res => {
          if (res.data) {
            this.userTypes = res.data;
          }
          else {
            this.$toasted.error('No response');
          }
        }, err => {
          this.$toasted.error(err);
        })
      },
      loadUsers() {
        this.loading = true;
        const {page, pageSize} = this.pager;
        getUsers(page, pageSize, this.filteredUser).subscribe(res => {
          // console.log(res);
          if (res.data) {
            const {current, data, pageSize, total, totalPages} = res.data;
            this.pager.pageSize = pageSize;
            this.pager.page = current;
            this.pager.total = total;
            this.pager.totalPages = totalPages;
            this.users = data;
          }
          this.loading = false;
        }, err => {
          this.$toasted.error(err);
          this.loading = false;
        })
      },
    },
    mounted() {
      this.loadUsers();
      this.loadUserTypes();
    }
  };
</script>
